package me.stone.stanimeclient.page.rank

import android.widget.NumberPicker
import android.widget.NumberPicker.OnValueChangeListener
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import me.stone.stanimeclient.core.common.utils.WhileViewSubscribed
import me.stone.stanimeclient.core.data.domain.fan.LoadRankDataCase
import me.stone.stanimeclient.core.data.domain.Result
import me.stone.stanimeclient.core.model.FanRankItem
import me.stone.stanimeclient.util.year
import java.util.Calendar
import javax.inject.Inject

@HiltViewModel
class RankViewModel @Inject constructor(
    private val loadRankDataCase: LoadRankDataCase
) : ViewModel(), OnValueChangeListener {

    private val _year = MutableStateFlow<Int?>(null)
    private val _page = MutableStateFlow(0)

    @OptIn(ExperimentalCoroutinesApi::class)
    private val _fullRankData = _year.flatMapLatest {
        loadRankDataCase(it)
    }.stateIn(viewModelScope, WhileViewSubscribed, Result.Loading)

    val rankData: Flow<Result<List<FanRankItem>>> = _page.combine(_fullRankData) { page, result ->
        when (result) {
            is Result.Loading -> Result.Loading
            is Result.Error -> Result.Error(result.error)
            is Result.Success -> {
                val data = result.data
                if (page < 0 || page >= data.size) {
                    Result.Error(IndexOutOfBoundsException("排行榜数据下标错误！"))
                } else {
                    Result.Success(data[page])
                }
            }
        }
    }

    fun changeShowPage(page: Int) {
        viewModelScope.launch {
            _page.emit(page)
        }
    }

    private val _rankYearDialogSign = MutableSharedFlow<Boolean>()
    val rankYearDialogSign: SharedFlow<Boolean> = _rankYearDialogSign
        .shareIn(viewModelScope, WhileViewSubscribed)

    val rankYearDisplay: StateFlow<String> = _year.map { year ->
        when (year) {
            null -> "首播时间：全部"
            2000 -> "首播时间：2000年以前"
            else -> "首播时间：${year}年"
        }
    }.stateIn(viewModelScope, WhileViewSubscribed, "首播时间：全部")

    private val _rankYears: List<Pair<String, Int?>> by lazy {
        listOf(
            "全部" to null,
            *(Calendar.getInstance().year downTo 2001).map { "${it}年" to it }.toTypedArray(),
            "2000年以前" to 2000
        )
    }

    val pickerMinValue: Int
        get() = 0

    val pickerMaxValue: Int
        get() = _rankYears.size - 1

    val pickerDisplayArray: Array<String>
        get() = _rankYears.map { it.first }.toTypedArray()

    private var _yearPickerIndex = 0

    override fun onValueChange(picker: NumberPicker?, oldVal: Int, newVal: Int) {
        _yearPickerIndex = newVal
    }

    fun showRankYearSelectorDialog() {
        viewModelScope.launch {
            _rankYearDialogSign.emit(true)
        }
    }

    fun submitRankYear() {
        viewModelScope.launch {
            _year.emit(_rankYears[_yearPickerIndex].second)
            _rankYearDialogSign.emit(false)
        }
    }

    fun cancelSelector() {
        viewModelScope.launch {
            _rankYearDialogSign.emit(false)
        }
    }

}